package com.min.main.service;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.min.common.entity.R;
import com.min.common.util.ShiroUtils;
import com.min.main.constant.UserConst;
import org.springframework.stereotype.Service;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.min.main.entity.MenuEntity;
import com.min.main.dao.PermissionDao;

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 权限表
 *
 * @author fengt
 * @date 2021-06-23 11:41:08
 */
@Service
public class MenuService extends ServiceImpl<PermissionDao, MenuEntity> {

    /**
     * 查询出菜单树
     * @return: com.min.common.entity.R
     * @author: fengt
     * @date: 2021/7/15 17:21
     **/
    public R menusTree() {
        final Long userId = ShiroUtils.getUser().getId();
        List<MenuEntity> menus = new ArrayList<>();
        if (UserConst.SUPER_USERS.contains(userId)) {
            menus = getMenusByUserId(0L);
        } else {
            menus = getMenusByUserId(userId);
        }
        return R.ok().put("menus", menus);
    }

    private List<MenuEntity> getMenusByUserId(Long userId) {
        List<MenuEntity> menus = userId.equals(0L) ? this.list() : this.baseMapper.listByUserId(userId);
        final List<MenuEntity> roots = menus.stream().filter(m -> m.getParentId().equals(0L)).collect(Collectors.toList());
        for (MenuEntity root : roots) {
            createChildren(root, menus);
        }

        return roots;
    }

    /**
     * 递归创建子节点
     * @param menu:
     * @param menus:
     * @return: void
     * @author: fengt
     * @date: 2021/7/21 14:49
     **/
    private void createChildren(MenuEntity menu, List<MenuEntity> menus) {
        final List<MenuEntity> children = menus.stream()
                .filter(m -> m.getParentId().equals(menu.getId()))
                .sorted(Comparator.comparing(MenuEntity::getSorter))
                .collect(Collectors.toList());

        if (!children.isEmpty()) {
            menu.setChildren(children);
            for (MenuEntity child : children) {
                createChildren(child, menus);
            }
        }
    }

    private List<Long> querySubIds(List<Long> ids) {
        final List<Long> subIds = this.listObjs(
                Wrappers.lambdaQuery(MenuEntity.class)
                        .select(MenuEntity::getId)
                        .in(MenuEntity::getParentId, ids),
                c -> Long.parseLong(c.toString()));

        if (!subIds.isEmpty()) {
            ids.addAll(querySubIds(subIds));
        }

        return ids;
    }

    public R removeWithSub(List<Long> ids) {
        final List<Long> temp = querySubIds(ids);
        return this.removeByIds(temp) ? R.ok() : R.error();
    }
}

